// Created on: Dec 11, 2014
//
// Author: wjinwen.1988@gmail.com

#ifndef CHI_SINGLETON_H
#define CHI_SINGLETON_H

#include <pthread.h>
#include <stdlib.h>

namespace chi {

template<typename T>
class Singleton {
 public:
  Singleton(const Singleton&) = delete;
  void operator=(const Singleton&) = delete;

  static T& instance() {
    pthread_once(&ponce_, &Singleton::init);
    return *value_;
  }

 private:
  Singleton();
  ~Singleton();

  
  static void init() {
    value_ = new T();
    ::atexit(destory);
  }

  static void destory() {
    typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];
    T_must_be_complete_type dummy; (void) dummy;
    
    delete value_;
  }

 private:
  static pthread_once_t ponce_;
  static T*             value_;
};

template<typename T>
pthread_once_t Singleton<T>::ponce_ = PTHREAD_ONCE_INIT;

template<typename T>
T* Singleton<T>::value_ = NULL;

}  // namespace chi 
#endif  // CHI_SINGLETON_H

